/**
 * 
 */
package eMdP.gestors;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.LinkedList;

import com.jme.math.Vector3f;
import com.jmex.physics.PhysicsSpace;

import eMdP.ElMensajeroDePekin;
import eMdP.classesBasiques.Escenari;
import eMdP.classesBasiques.Personatge;
import eMdP.classesBasiques.RegistrePuntuacio;

/**
 * @author redribbon
 *
 */
public class GestorFitxers {
	
	private static final String nomLLeFitxerTemps = "eMdP/maximesPuntuacionsTemps.emdp";
	private static final String nomLLeFitxerPaquets = "eMdP/maximesPuntuacionsPaquets.emdp";
	private static final String nomEscenaris = "eMdP/escenaris/llistatEscenaris.emdp";
	private static final String nomPersonatges = "eMdP/personatges/llistatPersonatges.emdp";
	private static final String fitxerConfiguracio = "eMdP/config.emdp";
	
	public static String[] llegirPerTemps(){
		int i=0;
		String linia="";
		String[] cadenaValors = new String[10];
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomLLeFitxerTemps).getPath();
		
		File f = new File(fitxer);
		try{
			if (f.exists()){
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				//entrada.ready();
				while((linia=entrada.readLine())!= null && i<10){
					cadenaValors[i]=linia;
					i++;
				}
				entrada.close();
				
			}else System.out.println("GestorPuntuacio::El fitxer de punts per temps no existeix");
		}catch(Exception e){System.out.println("GestorPuntuacio::ERROR AL LLEGIR EL FITXER!!");}
		
		return cadenaValors;
	}
	
	public static RegistrePuntuacio[] llegirPerPaquets()
	{
		RegistrePuntuacio[] registres = new RegistrePuntuacio[10];
		int mode = GestorConstants.MODE_PAQUETS;
		int idPersonatge = 0;
		String nomPersonatge = "";
		String nomEscenari = "";
		int valorPuntuacio = 0;
		String linia = "";
		//String[] cadenaValors = new String[10];
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomLLeFitxerPaquets).getPath();
		
		File f = new File(fitxer);
		try{
			if (f.exists()){
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				for(int i=0;i<10;i++)
				{
					buscarSeguentComençament(entrada);
					linia = saltarComentaris(entrada);
					idPersonatge = llegirEnter(linia);
					nomPersonatge = saltarComentaris(entrada);
					nomEscenari = saltarComentaris(entrada);
					linia = saltarComentaris(entrada);
					valorPuntuacio = llegirEnter(linia);
					registres[i] = new RegistrePuntuacio(mode, idPersonatge, nomPersonatge, nomEscenari, valorPuntuacio);
					//System.out.println("Registre "+i+": "+registres[i].toString());
				}
			}
		}catch(Exception e)
		{
			System.out.println("GestorPuntuacio::Error al llegir el fitxer de màximes puntuacions");
		}
		return registres;
	}
	
	public static void guardaRegistre(RegistrePuntuacio registre)
	{
		String fitxer;
		if(registre.getMode() == GestorConstants.MODE_TEMPS)
			fitxer = GestorFitxers.class.getClassLoader().getResource(nomLLeFitxerTemps).getPath();
		else
			fitxer = GestorFitxers.class.getClassLoader().getResource(nomLLeFitxerPaquets).getPath();
		
		File file = new File(fitxer);
		int comptador = 0;
		String linia;
		boolean trobat = false;
		RegistrePuntuacio[] registres = new RegistrePuntuacio[10];
		int mode = GestorConstants.MODE_PAQUETS;
		int idPersonatge = 0;
		String nomPersonatge = "";
		String nomEscenari = "";
		int valorPuntuacio = 0;
		
		try
		{
			if(file.exists())
			{
				// Creem el fitxer de lectura
				BufferedReader entrada = new BufferedReader( new FileReader( file ) );
				
				while(buscarSeguentComençament(entrada) && comptador < 10)
				{
					//buscarSeguentComençament(entrada);
					linia = saltarComentaris(entrada);
					System.out.println("linia: "+linia+", comptador: "+comptador);
					idPersonatge = llegirEnter(linia);
					nomPersonatge = saltarComentaris(entrada);
					System.out.println("nomPersonatge: "+nomPersonatge);
					nomEscenari = saltarComentaris(entrada);
					System.out.println("nomEscenari: "+nomEscenari);
					linia = saltarComentaris(entrada);
					System.out.println("valorPuntuacio: "+linia);
					valorPuntuacio = llegirEnter(linia);
					RegistrePuntuacio registreTmp = new RegistrePuntuacio(mode, idPersonatge, nomPersonatge, nomEscenari, valorPuntuacio);
					
					System.out.println("Puntuacio actual: "+registre.getValorPuntuacio());
					
					if(!trobat)
					{
						if(registreTmp.getValorPuntuacio() > registre.getValorPuntuacio())
						{
							registres[comptador] = registre;
							comptador++;
							registres[comptador] = registreTmp;
							trobat = true;
						}
						else
							registres[comptador] = registreTmp;
					}
					else
					{
						registres[comptador] = registreTmp;
					}
					comptador++;
				}
			}
			guardarPuntuacions(registres, mode);
		}
		catch (Exception e)
		{
			System.out.println("GestorFitxers::guardaRegistre error al guardar el registre");
			e.printStackTrace();
		}
	}
	
	public static void guardarPuntuacions(RegistrePuntuacio[] registres, int mode)
	{
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomLLeFitxerPaquets).getPath();
		File flle = new File(fitxer);
		try
		{
			BufferedWriter escriure = new BufferedWriter( new FileWriter( flle ) );
			String textCopiar = "# comentaris \n";
			
			for(int i=0;i<registres.length;i++)
			{
				textCopiar += "/\n";
				textCopiar += registres[i].getIdPersonatge()+"\n";
				textCopiar += registres[i].getNomPersonatge()+"\n";
				textCopiar += registres[i].getNomEscenari()+"\n";
				textCopiar += registres[i].getValorPuntuacio()+"\n";				
			}
			
			textCopiar += "\n";
			
			escriure.write(textCopiar);
			escriure.flush();
			escriure.close();
		}
		catch (Exception e)
		{}
	}
	
	public static void guardarPerTemps(String puntuacio){
		
		/* Carreguem els fitxers de lectura i escriptura */
		String fitxerLectura = GestorFitxers.class.getClassLoader().getResource(nomLLeFitxerTemps).getPath();
		File flle = new File(fitxerLectura);
		
		/* Posem els valors de puntuacio separats per Strings */
		String[] valorsNous = new String[4];
		valorsNous = puntuacio.split(" ");
		int punts = Integer.parseInt(valorsNous[0]);
		
		String linia="";
		String[] valors = new String[4];
		int cont = 0; 
		boolean trobat=false;
		String textCopiar="";
		try{
			if (flle.exists()){
				/* Creem el fitxer de lectura */
				BufferedReader entrada = new BufferedReader( new FileReader( flle ) );
				
				/* Mentres hi hagin linies per llegir, o n'hagi llegit menys de 9 (+el que entrem fa 10), ves llegint */
				while((linia=entrada.readLine())!= null && cont<9){
					if(!trobat)
					{
						/* Separem els valors d'aquella puntuacio */
						valors = linia.split(" "); //0 -> Punts, 1 -> nom, 2 -> Imatge, 3 -> pantalla
						
						/* Si el valor nou és més gran que l'actual, concatenem els valors nous, i posem trobat a true */
						if(Integer.parseInt(valors[0]) < punts){
							System.out.println("Valor més gran, entrem en pos: "+cont);
							if(cont==0) textCopiar+=puntuacio;
							else textCopiar+=puntuacio+"\n";
							trobat=true;
						}

					}
					/* Guardem els valors que copiarem al fitxer nou */
					textCopiar+=linia+"\n";
					cont++;
				}
				
				/* Un cop recorregut les 10 primeres posicions del fitxer el tanquem */
				entrada.close();
				
				/* Obrim de nou el fitxer de puntuacions i ho sobrescrivim tot amb el que tenim guardat */
				BufferedWriter escriure = new BufferedWriter( new FileWriter( flle ) );
				
				escriure.write(textCopiar);
				escriure.flush();
				escriure.close();
				
			}else System.out.println("GestorPuntuacio::El fitxer de punts per temps no existeix");
		}catch(Exception e){System.out.println("GestorPuntuacio::ERROR AL LLEGIR/ESCRIURE AL FITXER!!");}
		
	}
	
	public static Escenari carregarEscenari(int id,PhysicsSpace espaiFisic){
		
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomEscenaris).getPath();
		boolean error=false;
		String linia;
		int idFinal=0;
		String nomFinal="";
		String descripcioFinal="";
		int numBusties=0;
		int numPNJS=0;
		int numFurgos=0;
		int numJugadors=0;
		LinkedList<Vector3f> busties = new LinkedList<Vector3f>();
		LinkedList<Vector3f> PNJS = new LinkedList<Vector3f>();
		LinkedList<Vector3f> furgonetes = new LinkedList<Vector3f>();
		LinkedList<Vector3f> jugadors = new LinkedList<Vector3f>();
		
		/* Creem l'Escenari que retornarem */
		Escenari escenari;
		
		File f = new File(fitxer);
		try{
			if (f.exists()){
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				/* Aixó ens col·loca just a la linia anterior al començament de l'info de l'escenari */
				error = buscarComençament(id, entrada);
				linia = saltarComentaris(entrada);
				/* llegim la id */
				idFinal = llegirEnter(linia);
				System.out.println("GestorFitxers:: ID: "+idFinal);
				/* Llegim el nom de l'escenari */
				nomFinal = saltarComentaris(entrada);
				System.out.println("GestorFitxers:: NOM: "+nomFinal);
				/* Llegim la Descripcio de l'escenari */
				descripcioFinal = saltarComentaris(entrada);
				System.out.println("GestorFitxers:: DESCRIPCIO: "+descripcioFinal);
				linia = saltarComentaris(entrada);
				/* Llegim el numero de busties que hi ha a l'escenari */
				numBusties = llegirEnter(linia);
				System.out.println("GestorFitxers:: NUM BUSTIES: "+numBusties);
				linia = saltarComentaris(entrada);
				/* Llegim la posicio de totes les busties */
				for(int i=0;i<numBusties;i++){
					Vector3f pos = new Vector3f(llegirVector3f(linia));
					busties.add(pos);
					linia = saltarComentaris(entrada);
				}
				/* Llegim el numero de PNJ */
				numPNJS = llegirEnter(linia);
				System.out.println("GestorFitxers:: NUM PNJ: "+numPNJS);
				linia = saltarComentaris(entrada);
				/* Llegim la posicio de tots els PNJ */
				for(int i=0;i<numPNJS;i++){
					Vector3f pos = new Vector3f(llegirVector3f(linia));
					PNJS.add(pos);
					linia = saltarComentaris(entrada);
				}
				/* Llegim el numero de Furgonetes */
				numFurgos = llegirEnter(linia);
				System.out.println("GestorFitxers:: NUM FURGOS: "+numFurgos);
				linia = saltarComentaris(entrada);
				/* Guardem el punt de descàrrega de l'Escenari */
				for(int i=0;i<numFurgos;i++){
					Vector3f pos = new Vector3f(llegirVector3f(linia));
					furgonetes.add(pos);
					linia = saltarComentaris(entrada);
				}
				/* Llegim el numero de Jugadors */
				numJugadors = llegirEnter(linia);
				System.out.println("GestorFitxers:: NUM JUGADORS: "+numJugadors);
				linia = saltarComentaris(entrada);
				/* Guardem el punt de descàrrega de l'Escenari */
				for(int i=0;i<numJugadors;i++){
					Vector3f pos = new Vector3f(llegirVector3f(linia));
					jugadors.add(pos);
					linia = saltarComentaris(entrada);
				}
				entrada.close();
			}
		}catch(Exception e){System.out.println("GestorFitxers::ERROR AL Crear l'escenari!!"+error);}
		
		/* Creem l'escenari amb totes les variables agafades del fitxer i ho retornem */
		escenari = new Escenari(idFinal,nomFinal,descripcioFinal,numBusties,busties,numPNJS,PNJS,numFurgos,furgonetes,numJugadors,jugadors,espaiFisic.createStaticNode());
		
		return escenari;
	}
	
	public static Personatge carregarPersonatge(int id, PhysicsSpace espaiFisic)
	{
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomPersonatges).getPath();
		boolean error=false;
		String linia;
		int idFinal=0;
		String nomFinal="";
		String descripcioFinal="";
		String model = "";
		String textura = "";
		float força=0;
		
		/* Creem el Personatge que retornarem */
		Personatge p = new Personatge();
		
		File f = new File(fitxer);
		try{
			if (f.exists()){
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				/* Aixó ens col·loca just a la linia anterior al començament de l'info del Personatge */
				error = buscarComençament(id, entrada);
				linia = saltarComentaris(entrada);
				/* llegim la id */
				idFinal = llegirEnter(linia);
				/* Llegim el nom del Personatge */
				nomFinal = saltarComentaris(entrada);
				/* Llegim la Descripcio del Personatge */
				descripcioFinal = saltarComentaris(entrada);
				// Llegimn el model del personatge
				model = saltarComentaris(entrada);
				// llegim la textura del personatge
				textura = saltarComentaris(entrada);
				// Llegim la Força que tindrà el Personatge
				linia = saltarComentaris(entrada);
				força = llegirDecimal(linia);
			
				entrada.close();
			}
		}
		catch(Exception e)
		{
			System.out.println("GestorFitxers::ERROR AL Crear el Personatge!!"+error);
		}
		//p = new Personatge("Personatge"+nomFinal, descripcioFinal, textura, model, espaiFisic.createDynamicNode(), força, idFinal);
		model = GestorConstants.DIRECCIO_MODELS_PERSONATGES+model;
		p = new Personatge("Personatge"+nomFinal, descripcioFinal, textura, model, espaiFisic, força, idFinal);
		return p;
	}
	
	public static LinkedList<String> getNomsPersonatges()
	{
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomPersonatges).getPath();
		
		LinkedList<String> llista = new LinkedList<String>();
		
		boolean trobat=false;
		String linia;
		String nom = "";
		
		File f = new File(fitxer);
		try{
			if (f.exists()){
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				while(entrada.readLine() != null)
				{
					/* Aixó ens col·loca just a la linia anterior al començament de l'info del Personatge */
					trobat = buscarSeguentComençament(entrada);
					if(trobat)
					{
						/* llegim la id */
						linia = saltarComentaris(entrada);
						/* Llegim el nom del Personatge */
						nom = saltarComentaris(entrada);
						llista.add(nom);
					}
				}
				entrada.close();
			}
		}catch(Exception e)
		{
			System.out.println("GestorFitxers::ERROR al carregar les dades d'un personatge"+trobat);
		}
		
		return llista;
	}
	
	public static LinkedList<String> getNomsPantalles()
	{
		String fitxer = GestorFitxers.class.getClassLoader().getResource(nomEscenaris).getPath();
		
		LinkedList<String> llista = new LinkedList<String>();
		
		boolean trobat=false;
		String linia;
		String nom = "";
		
		File f = new File(fitxer);
		try{
			if (f.exists()){
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				while(entrada.readLine() != null)
				{
					/* Aixó ens col·loca just a la linia anterior al començament de l'info del Personatge */
					trobat = buscarSeguentComençament(entrada);
					if(trobat)
					{
						/* llegim la id */
						linia = saltarComentaris(entrada);
						/* Llegim el nom del Personatge */
						nom = saltarComentaris(entrada);
						llista.add(nom);
					}
				}
				entrada.close();
			}
		}catch(Exception e)
		{
			System.out.println("GestorFitxers::ERROR al carregar les dades d'un personatge"+trobat);
		}
		
		return llista;
	}
	
	public LinkedList<String> getNomsEscenaris(){
		LinkedList<String> llistat = new LinkedList<String>();
		
		return llistat;
	}
	
	public static int[] llegirConfiguracio()
	{
		String fitxer = GestorFitxers.class.getClassLoader().getResource(fitxerConfiguracio).getPath();
		File f = new File(fitxer);
		String linia;
		int tmp;
		
		int[] valors = new int[4];
		for(int i=0;i<4;i++)
			valors[i] = -1;
		try
		{
			if(f.exists())
			{
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				linia = saltarComentaris(entrada);
				// Llegim ample (width)
				if(linia.startsWith("AMPLE="))
				{
					tmp = Integer.parseInt(linia.substring(6));
					if(tmp == 800 || tmp == 1024)
						valors[0] = tmp;
				}
				else
					System.out.println("GestorFitxers::llegirConfiguracio error la primera linia no és ample");
				// Llegim alt (height)
				linia = saltarComentaris(entrada);
				if(linia.startsWith("ALT="))
				{
					tmp = Integer.parseInt(linia.substring(4));
					if(tmp == 600 || tmp == 768)
						valors[1] = tmp;
				}
				else
					System.out.println("GestorFitxers::llegirConfiguracio error la segona linia no és alt");
				// Llegim fullscreen
				linia = saltarComentaris(entrada);
				if(linia.startsWith("PANTALLACOMPLETA="))
				{
					tmp = Integer.parseInt(linia.substring(17));
					if(tmp == 0 || tmp == 1)
						valors[2] = tmp;
				}
				else
					System.out.println("GestorFitxers::llegirConfiguracio error la tercera linia no és pantalla completa");
				// Llegim so
				linia = saltarComentaris(entrada);
				if(linia.startsWith("SO="))
				{
					tmp = Integer.parseInt(linia.substring(3));
					if(tmp == 0 || tmp == 1)
						valors[3] = tmp;
				}
				else
					System.out.println("GestorFitxers::llegirConfiguracio error la quarta linia no és so completa");
				
				entrada.close();
			}
		} catch (Exception e)
		{
			System.out.println("GestorFitxers::llegirConfiguracio error al llegir el fitxer");
		}
		
		return valors;
	}
	
	public static void guardarConfiguracio()
	{
		int ample = ElMensajeroDePekin.getResolucio()[0];
		int alt = ElMensajeroDePekin.getResolucio()[1];
		boolean pantallacompleta = ElMensajeroDePekin.isPantallaCompleta();
		boolean so = ElMensajeroDePekin.isSo();
		String control_1 = ElMensajeroDePekin.getControls()[0];
		String control_2 = ElMensajeroDePekin.getControls()[1];
		String control_3 = ElMensajeroDePekin.getControls()[2];
		String control_4 = ElMensajeroDePekin.getControls()[3];
		
		String fitxer = GestorFitxers.class.getClassLoader().getResource(fitxerConfiguracio).getPath();
		File f = new File(fitxer);
		String text = "";
		String linia;
		
		try
		{
			if(f.exists())
			{
				BufferedReader entrada = new BufferedReader( new FileReader( f ) );
				while((linia = entrada.readLine())!= null)
				{
					if(linia.startsWith("AMPLE="))
						text += "AMPLE="+ample+"\n";
					else if(linia.startsWith("ALT="))
						text += "ALT="+alt+"\n";
					else if(linia.startsWith("PANTALLACOMPLETA="))
					{
						if(pantallacompleta)
							text += "PANTALLACOMPLETA=1"+"\n";
						else
							text += "PANTALLACOMPLETA=0"+"\n";
					}
					else if(linia.startsWith("SO="))
					{
						if(so)
							text += "SO=1"+"\n";
						else
							text += "SO=0"+"\n";
					}
					else if(linia.startsWith("CONTROL_1="))
						text += "CONTROL_1="+control_1+"\n";
					else if(linia.startsWith("CONTROL_2="))
						text += "CONTROL_2="+control_2+"\n";
					else if(linia.startsWith("CONTROL_3="))
						text += "CONTROL_3="+control_3+"\n";
					else if(linia.startsWith("CONTROL_4="))
						text += "CONTROL_4="+control_4+"\n";
					else
						text += linia+"\n";
				}
				entrada.close();
				
				BufferedWriter escriure = new BufferedWriter( new FileWriter( f ) );
				
				escriure.write(text);
				escriure.flush();
				escriure.close();
			}
		} catch (Exception e) {}
	}
	
	/**
	 * Metode per col·locar el punter del fitxer just a la posició a on hi ha '/' abans de l'id de l'escenari
	 * 
	 * @param idEscenari id de l'Escenari que volem
	 * @param fitxer Fitxer de configuració de tots els escenaris
	 * @return trobat En cas que sigui false, vol dir que no ho ha trobat, per tant error!
	 */
	private static boolean buscarComençament(int id, BufferedReader fitxer){
		boolean trobat = false;
		/* Fem un recorregut per el fitxer fins arribar a l'id indicat */
		for(int i=0; i<=id; i++)
			trobat = buscarSeguentComençament(fitxer);
		
		/* Retornem trobat per poder fer un control d'errors, en cas que sigui false, ERROR! */
		return trobat;
	}
	
	private static boolean buscarSeguentComençament(BufferedReader fitxer)
	{
		boolean trobat = false;
		String linia = "";
		try
		{
			linia = fitxer.readLine();
			// Mentre no trobem el començament de l'escenari segueix llegint
			while(linia != null && !(trobat = linia.startsWith("/"))){
				linia = fitxer.readLine();
			}
		}
		catch (Exception e)
		{
			System.out.println("GestorFitxers::buscarSeguentComençament error al llegir fitxer");
		}
		return trobat;
	}
	
	/**
	 * Converteix un String en un enter
	 * @param linia 
	 * @return enter Retorna la cadena transformada en un Enter.
	 */
	private static int llegirEnter(String linia){
		return Integer.parseInt(linia);
	}
	
	/**
	 * Converteix un String en un decimal
	 * @param linia 
	 * @return enter Retorna la cadena transformada en un decimal.
	 */
	private static float llegirDecimal(String linia){
		return Float.parseFloat(linia);
	}

	/**
	 * Metode per convertir una cadena tipus: 0,0,0 en un Vector3f (0,0,0)
	 * @param linia String que conté la cadena
	 * @return vector3f Conté l'String convertit en un Vector3f
	 */
	private static Vector3f llegirVector3f(String linia){
		String[] coordenades = new String[3];
		Vector3f vector = new Vector3f();
		try{
			coordenades = linia.split(",");
			vector.set(Float.parseFloat(coordenades[0]),Float.parseFloat(coordenades[1]),Float.parseFloat(coordenades[2]));
			//vector.set(Integer.parseInt(coordenades[0]), Integer.parseInt(coordenades[1]), Integer.parseInt(coordenades[2]));
		}catch(Exception e){System.out.println("GestorFitxer::Error al llegir un String i convertir-lo en un Vector3f! "+linia);}
		return vector;
	}
	
	/**
	 * Metode per saltar totes les línies que continguin comentaris. Un comentari s'escriu amb el coixinet '#'
	 * @param fitxer Fitxer a on hi ha la configuració de l'Escenari
	 * @return linia La següent línia que no conté #
	 */
	private static String saltarComentaris(BufferedReader fitxer){
		String linia = "";
		try{
			linia = fitxer.readLine();
			/* Mentre la linia contingui # (Comentaris) i no arribem al final del fitxer, anem llegint */ 
			while(linia!= null && linia.startsWith("#")){
				linia = fitxer.readLine();
			}
		}catch(Exception e){System.out.println("GestorFitxers::Error al saltar Comentaris!");}
		return linia;
	}
	
}
